package com.zyl.Ecs.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.zyl.Ecs.common.exception.EcsException;
import com.zyl.Ecs.common.response.ResultCode;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @version v1.0
 * @ProjectName: Ecs
 * @Package: com.zyl.Ecs.common.utils
 * @ClassName: JwtUtil
 * @Description TODO (JWT工具类)
 * @Author 翟玉龙
 * @Date 2024/12/4-11:28
 */
public class JwtUtil {
    /**
     * 头部字段名
     */
    public final static String AUTH_HEADER_KEY = "Authorization";
    /**
     * 过期时间，单位：分钟
     */
    private static final int EXPIRE_TIME_MINUTE = 30 * 24 * 60;
    /**
     * jwt 密钥，用于生成签名
     */
    private static final String SECRET = "zyl_jwt_secret";

    /**
     * 生成JWT字符串
     *
     * @param accountId 用户id
     * @param info   附带的其他信息
     *               Map的value只能存放的值的类型为：Map, List, Boolean, Integer, Long, Double, String and Date
     *               注意，map的value如果是null的话，也会报错
     * @return jwtToken
     */
    public static String sign(String accountId, Map<String, Object> info) {
        try {
            // 当前时间
            Calendar calendar = Calendar.getInstance();

            // 计算失效时间（失效时间 = 当前签发时间 + 有效时长）
            calendar.add(Calendar.MINUTE, EXPIRE_TIME_MINUTE);

            // 转换为Date类型
            Date date = calendar.getTime();

            // 使用HMAC256算法加密密钥（相当于JWT的头部和签名）
            Algorithm algorithm = Algorithm.HMAC256(SECRET);

            // 生成Token字符串
            return JWT.create()
                    // 将userId保存到Token中
                    .withAudience(accountId)
                    // 设置Token失效时间
                    .withExpiresAt(date)
                    // 存放自定义数据
                    .withClaim("info", info)
                    // 签名
                    .sign(algorithm);
        } catch (Exception e) {
            CUtil.logInfo(e.getMessage());
            return null;
        }
    }

    /**
     * 根据token获取userId
     *
     * @param token Token字符串
     * @return userId
     */
    public static String getAccountId(String token) {
        try {
            return JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 根据token获取自定义数据info
     *
     * @param token Token字符串
     * @return 从Token中解析出的自定义信息
     */
    public static Map<String, Object> getInfo(String token) {
        try {
            return JWT.decode(token).getClaim("info").asMap();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 校验token
     *
     * @param token Token字符串
     * @throws EcsException Token校验失败则抛出异常（为空或内容不合法）
     */
    public static void checkSign(String token) throws EcsException {
        if (ObjectUtil.notHasText(token)) {
            throw new EcsException(ResultCode.TOKEN_BLANK);
        }
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        try {
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new EcsException(ResultCode.TOKEN_INVALID);
        }

    }
}
